<template>
  <div>
    <div>模型边界线EdgesGeometry</div>
    <div ref="webgl" id="webgl"></div>
  </div>
</template>
<script lang="ts" setup>
  import * as THREE from 'three';
  import { GLTFLoader, OrbitControls } from 'three/addons';
  import { onMounted, ref } from 'vue';

  const webgl: any = ref(null);
  let scene: any = null;
  let camera: any = null;
  let render: any = null;
  onMounted(() => {
    init();
  });
  function init() {
    scene = new THREE.Scene();
    const width = 500;
    const height = 300;
    camera = new THREE.PerspectiveCamera(30, width / height, 1, 10000);
    camera.position.set(-100, 300, 300);
    camera.lookAt(scene.position);
    render = new THREE.WebGLRenderer();
    render.setSize(width, height);
    webgl.value.appendChild(render.domElement);
    new OrbitControls(camera, render.domElement);
    const amLight = new THREE.AmbientLight(0xffffff);
    scene.add(amLight);
    const helper = new THREE.AxesHelper(200);
    scene.add(helper);

    const pointLight = new THREE.PointLight(0xffffff);

    pointLight.position.set(100, 100, 100);
    scene.add(pointLight);
    const pointLightHelper = new THREE.PointLightHelper(pointLight);
    scene.add(pointLightHelper);
    const material = new THREE.MeshLambertMaterial({
      color: 0x11ffff,
      transparent: true, //开启透明
      opacity: 0.7, //设置透明度
      // side: THREE.DoubleSide,
    });
    // 长方体边线
    // const geometry = new THREE.BoxGeometry(50, 50, 50);
    // 圆柱边线
    // const geometry = new THREE.CylinderGeometry(60, 60, 100, 30);

    const shape = new THREE.Shape([
      new THREE.Vector2(0, 0),
      new THREE.Vector2(150, 0),
      new THREE.Vector2(75, 150),
    ]);
    const geometry = new THREE.ExtrudeGeometry(shape, {
      depth: 20,
    });
    const mesh = new THREE.Mesh(geometry, material);
    scene.add(mesh);

    // 相邻面法线夹角大于30度，才会显示线条
    const edges = new THREE.EdgesGeometry(geometry, 30);
    const edgesMaterial = new THREE.LineBasicMaterial({
      color: 0x00ffff,
    });
    const line = new THREE.LineSegments(edges, edgesMaterial);
    mesh.add(line);
    const loader = new GLTFLoader();
    loader.load(
      '../../../../public/feiji.gltf',
      function (gltf) {
        // 递归遍历设置每个模型的材质，同时设置每个模型的边线
        gltf.scene.traverse((obj: any) => {
          console.log('obj', obj);
          if (obj.isMesh) {
            // 模型材质重新设置
            obj.material = new THREE.MeshLambertMaterial({
              color: 0x004444,
              transparent: true,
              opacity: 0.5,
            });
            // 模型边线设置
            const edges = new THREE.EdgesGeometry(obj.geometry, 3);
            const edgesMaterial = new THREE.LineBasicMaterial({
              color: 0x00ffff,
            });
            const line = new THREE.LineSegments(edges, edgesMaterial);
            obj.add(line);
          }
        });
        gltf.scene.translateZ(200);
        scene.add(gltf.scene);
      },
      () => {},
      (err) => {
        console.log('errpr', err);
      },
    );
    renderFun();
  }
  function renderFun() {
    render.render(scene, camera);
    requestAnimationFrame(renderFun);
  }
</script>
<style lang=""></style>
